﻿using KinonekoSoftware.Foundation.Bus;

namespace KinonekoSoftware.CodariaDB.Runtimes
{
    public abstract partial class Engine
    {
        protected private RepositoryOpenContext _context;
        
        

        /// <summary>
        /// 打开数据引擎
        /// </summary>
        /// <param name="context">数据库打开上下文</param>
        /// <param name="create">数据库打开上下文</param>
        /// <exception cref="ArgumentNullException">如果任意参数为空的话</exception>
        public void Open(RepositoryOpenContext context, bool create = false)
        {
#if DEBUG || RELEASE
            var sw = new Stopwatch();
            sw.Start();
#endif
            if (context is null) throw new ArgumentNullException(nameof(context));
            if (context.Logger is null) throw new ArgumentNullException(nameof(Logger));
            if (context.Repository is null) throw new ArgumentNullException(nameof(Repository));

            Queue = context.Queue;

            //
            // call the virtual method
            OnDatabaseOpeningInternal(context);
            OnDatabaseOpening(context);

            if (create)
            {

            }
#if DEBUG || RELEASE
            EngineOpenElapsedTime = sw.ElapsedMilliseconds;
            sw.Stop();
#endif
            _context      = context;
            IsInitialized = true;
        }

        internal void Initialize() => OnInitialize();

        protected virtual void OnInitialize()
        {

        }

        /// <summary>
        /// 打开数据引擎（内部提前）
        /// </summary>
        /// <param name="context">数据库打开上下文</param>
        protected internal virtual void OnDatabaseOpeningInternal(RepositoryOpenContext context) {}

        /// <summary>
        /// 打开数据引擎
        /// </summary>
        /// <param name="context">数据库打开上下文</param>
        protected abstract void OnDatabaseOpening(RepositoryOpenContext context);


        /// <summary>
        /// 关闭数据引擎
        /// </summary>
        /// <param name="repository">数据库</param>
        /// <param name="logger">日志记录器</param>
        public void Close(IRepository repository, ILogger logger)
        {
            OnDatabaseClosingInternal(logger);
            OnDatabaseClosing(logger);
            IsInitialized = false;
            Version       = 0;
        }


        /// <summary>
        /// 关闭数据引擎（内部提前）
        /// </summary>
        protected internal virtual void OnDatabaseClosingInternal(ILogger logger) {}


        /// <summary>
        /// 关闭数据引擎
        /// </summary>
        protected abstract void OnDatabaseClosing(ILogger logger);

        /// <summary>
        /// 用来指示当前引擎是否修改。
        /// </summary>
        protected void Modified()
        {
            Version++;
        }


        /// <summary>
        /// 当前数据库版本
        /// </summary>
        public int Version { get; private set; }

        /// <summary>
        /// 用于获取当前引擎的唯一标识符。
        /// </summary>
        public abstract string EngineID { get; }

        /// <summary>
        /// 用去获取当前引擎是否已经加载。
        /// </summary>
        public bool IsInitialized { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public IMessageBus<DB_MSG> Queue { get; private set; }

        /// <summary>
        /// 打开引擎所需要的开销。
        /// </summary>
        public long EngineOpenElapsedTime { get; private set; }
    }
}